using System.Collections.Generic;

namespace Test.ConsoleProgram.Algorithm.Solution
{
    [TestDescription("算法: 0227. 基本计算器 II")]
    public class No0227_Calculate : AbsBaseTestItem
    {
        /*
        给你一个字符串表达式 s ，请你实现一个基本计算器来计算并返回它的值。
        整数除法仅保留整数部分。
        示例 1：
            输入：s = "3+2*2"
            输出：7
        示例 2：
            输入：s = " 3/2 "
            输出：1
        示例 3：
            输入：s = " 3+5 / 2 "
            输出：5
        提示：
            1 <= s.length <= 3 * 105
            s 由整数和算符 ('+', '-', '*', '/') 组成，中间由一些空格隔开
            s 表示一个 有效表达式
            表达式中的所有整数都是非负整数，且在范围 [0, 231 - 1] 内
            题目数据保证答案是一个 32-bit 整数
        */

        public override void OnTest()
        {
            Assert.TestExe(Calculate, "3+2*2", 7);
            Assert.TestExe(Calculate, " 3/2 ", 1);
            Assert.TestExe(Calculate, " 3+5 / 2 ", 5);
        }

        public int Calculate(string s)
        {
            Stack<int> stack = new Stack<int>();
            char preSign = '+';
            int num = 0;
            int n = s.Length;
            for (int i = 0; i < n; i++)
            {
                char c = s[i];
                if (char.IsNumber(c))
                {
                    num = num * 10 + c - '0';
                }
                if (!char.IsNumber(c) && c != ' ' || i == n - 1)
                {
                    switch (preSign)
                    {
                        case '+':
                            stack.Push(num);
                            break;
                        case '-':
                            stack.Push(-num);
                            break;
                        case '*':
                            stack.Push(stack.Pop() * num);
                            break;
                        case '/':
                            stack.Push(stack.Pop() / num);
                            break;
                    }
                    preSign = c;
                    num = 0;
                }
            }
            int result = 0;
            while (stack.Count > 0)
            {
                result += stack.Pop();
            }
            return result;
        }
    }
}
